var express = require('express');
var router = express.Router();
var superagent = require('superagent');
var request = require('request');

var xml2js = require('xml2js');
var async  = require( 'async'); // 同步控制
var CONFIG = require('../../common/config');
var CODE = require('../../common/code');
var WX = require('../../common/util/wx');

var checkUtil = require('./util/checkUtil');
var payUtil = require('./util/payUtil');




//------------------------------------------------------------------
/* GET payment listing. */
router.get('/', function(req, res, next) {
    res.send('Respond From Payment!');
});

//------------------------------------------------------------------
/* 调用微信支付[统一下单]API (测试用)
 * 方式:POST
 * 参数: device:
 * 参数: uuid: 设备唯一标识
 * 参数: orderNo: 订单号
 * 参数: fee: 订单价格(单位分)
 * */
function getUnifiedOrder(req, res, next) {
    // get parameter
    var device = req.body.device || req.query.device;// TODO
    var uuid = req.body.uuid || req.query.uuid || '';

    // 客户端订单号
    var orderNo = req.body.orderNo || req.query.orderNo || null;
    // 订单价格(单位分)
    var fee = Number(req.body.fee || req.query.fee || '0');

    // return function
    function ret_func(success, msg, data){
        var obj = {
            success:success,
            msg:msg,
            data:data
        };
        // 返回
        res.set('Content-Type', 'application/json');
        res.json(obj);
    }

    if(!orderNo) {
        return ret_func(0, '无效订单');
    }

    // parameter
    var timeStamp = Math.floor(Date.now()/1000)+"";
    var out_trade_no = orderNo + timeStamp + payUtil.genNonceStr(8,1);
    var appid = "wxb6504bf6ff28cb10";// 68c4365227330c448f22df66b8763266;
    var attach =  JSON.stringify({
        uid: 0, id: 0, type: 0
    });// TODO
    var body = "测试商品";// TODO
    var mch_id = "1419473302";
    var nonce_str = payUtil.genNonceStr(32);
    var total_fee = fee;
    // 接收微信支付异步通知回调地址，通知url必须为直接可访问的url，不能携带参数
    var notify_url = 'http://paycb.itbour.com/payment/chkWxPayNotify';// DEBUG
    var trade_type = "APP";
    var openid = "";// TODO
    var ip = "127.0.0.1";// TODO
    // 调用微信支付[统一下单]API
    var url = "https://api.mch.weixin.qq.com/pay/unifiedorder";

    var param = {
        appid: appid,
        attach: attach,
        body: body,
        mch_id: mch_id,
        nonce_str: nonce_str,
        notify_url: notify_url,
        //openid: openId,
        out_trade_no: out_trade_no,
        spbill_create_ip: ip,
        total_fee: total_fee,
        trade_type: trade_type,
        //package: "prepay_id="+prepayId,
        //signType: "MD5",
        //timeStamp: Math.floor(Date.now()/1000)+""
    };

    var formData  = "<xml>";
    formData  += "<appid>"+appid+"</appid>";  // 应用ID(必填)
    formData  += "<attach>"+attach+"</attach>"; // 附加数据
    formData  += "<body>"+body+"</body>";// 商品或支付单简要描述
    formData  += "<mch_id>"+mch_id+"</mch_id>";// 商户号(必填)
    formData  += "<nonce_str>"+nonce_str+"</nonce_str>"; //随机字符串,不长于32位(必填)
    // 支付成功后微信服务器通过POST请求通知这个地址
    formData  += "<notify_url>"+notify_url+"</notify_url>";// 通知地址(必填)
    //formData  += "<openid>"+openid+"</openid>";
    formData  += "<out_trade_no>"+out_trade_no+"</out_trade_no>";// 商户订单号(必填)
    formData  += "<spbill_create_ip>"+ip+"</spbill_create_ip>";// 终端IP(必填)
    formData  += "<total_fee>"+total_fee+"</total_fee>";// 总金额(必填)
    // APP/JSAPI/NATIVE(会返回code_url)
    formData  += "<trade_type>"+trade_type+"</trade_type>";// 交易类型(必填)
    formData  += "<sign>"+payUtil.calcWxPaySign(param)+"</sign>";
    formData  += "</xml>";

    request({url:url,method:'POST',body: formData},function(err,response,retBody){
        if(!err && response.statusCode == 200){
            console.log(retBody);
            //var prepay_id = getXMLNodeValue('prepay_id', retBody.toString("utf-8"));
            //if(prepay_id) {
            //  var tmp = prepay_id.split('[');
            //  var tmp2 = tmp[2].split(']');
            //  var prepayId = tmp2[0];
            //}

            var parser = new xml2js.Parser({ trim:true, explicitArray:false, explicitRoot:false });
            parser.parseString((retBody||'').toString("utf-8"), function(parseErr, parseRet){
                if(parseErr) {
                    console.log('payment.js [getUnifiedOrder] parser xml Err: '+parseErr);
                    return ret_func(0, CODE.OPERATION_FAILED);
                }

                if((parseRet.return_code||'')=='SUCCESS' && parseRet.prepay_id) {
                    var prepayId = parseRet.prepay_id || '';

                    // 统一下单接口返回正常的prepay_id，再按签名规范重新生成签名后，将数据传输给APP。
                    // 参与签名的字段名为appId，partnerId，prepayId，nonceStr，timeStamp，package。
                    // 注意：package的值格式为Sign=WXPay
                    var param2 = {
                        appId: appid,
                        partnerId: mch_id,
                        prepayId: prepayId,
                        nonceStr: payUtil.genNonceStr(32),
                        timeStamp: Math.floor(Date.now()/1000)+"",
                        package: "Sign=WXPay"
                    };
                    var sign2 = payUtil.calcWxPaySign(param2);

                    return ret_func(1, CODE.OPERATION_SUCCESS, {
                        prepayId:param2.prepayId,
                        nonceStr:param2.nonceStr,
                        timeStamp:param2.timeStamp,
                        sign:sign2
                    });

                } else {
                    return ret_func(0, parseRet.return_msg || '预付单信息获取失败');
                }
            });
        }
    });
}
router.get('/getUnifiedOrder', getUnifiedOrder);
router.post('/getUnifiedOrder', getUnifiedOrder);

//------------------------------------------------------------------
/* 根据订单信息创建支付订单 (APP支付/H5支付)
 * 方式:POST
 * 参数: device: 请求来源
 * 参数: uuid: 设备唯一标识
 * 参数: userId: 用户唯一标识
 * 参数: openId[可选]: 微信H5支付用
 * 参数: tradeObjId: 订单唯一标识
 * 参数: type: 商品订单:10, 发票订单:20
 * 返回:
 * {"success":1,
 *  "msg":"成功",
 *  "data":{
 *      "prepayId": 1234567,
 *      "nonceStr": "qwertyuiopsdfghjkl",
 *      "timeStamp": 999990909090,
 *      "sign": "QWKSJDFHGJHDFHHDHH"
 *   }
 * }
 * */
function createPayOrder(req, res, next) {
    var device = checkUtil.stringFromReq(req, 'device');
    if(!device) {
        return payUtil.ret_func_json(0,CODE.DEVICE_EMPTY,{},res);
    }

    var uuid = checkUtil.stringFromReq(req, 'uuid');
    if(!uuid) {
        return payUtil.ret_func_json(0,CODE.UUID_EMPTY,{},res);
    }

    var userId = checkUtil.numberFromReq(req, 'userId');
    if(!userId) {
        return payUtil.ret_func_json(0,CODE.USER_ID_EMPTY,{},res);
    }

    var openId = checkUtil.stringFromReq(req, 'openId') || '';

    var tradeObjId = checkUtil.numberFromReq(req, 'tradeObjId');
    if(!tradeObjId) {
        return payUtil.ret_func_json(0,'订单ID为空',{},res);
    }

    var type = checkUtil.numberFromReq(req, 'type');
    if(!type) {
        return payUtil.ret_func_json(0,'订单类型为空',{},res);
    }

    // 创建微信支付订单时（开始调用微信支付时），就将订单状态设置为：支付失败
    //payUtil.updOrderStateOnly(tradeObjId, type, CONFIG.TRADE_ORDER_STATE_PAY_FAIL, userId, function(error){
    //if(error){
    //    return payUtil.ret_func_json(0, CODE.OPERATION_FAILED,{},res);
    //}
    payUtil.getUnifiedOrder(device, userId, openId, tradeObjId, type, function(error, ret){
        if(error){
            console.log(error);
            return payUtil.ret_func_json(0, error||CODE.OPERATION_FAILED,{},res);
        }
        return payUtil.ret_func_json(1, CODE.OPERATION_SUCCESS,ret,res);
    });
    //});


}
router.get('/createPayOrder', createPayOrder);
router.post('/createPayOrder', createPayOrder);

//------------------------------------------------------------------
/* 根据订单信息创建支付订单 (网页支付)
 * 方式:POST
 * 参数: device: 请求来源
 * 参数: uuid: 设备唯一标识
 * 参数: userId: 用户唯一标识
 * 参数: tradeObjId: 订单唯一标识
 * 参数: type: 商品订单:10, 发票订单:20
 * 返回:
 * {"success":1,
 *  "msg":"成功",
 *  "data":{
 *      "prepay_id": "wx20170301114917740287da3c0256350262",
 *      "code_url": "weixin://wxpay/bizpayurl?pr=8RODogK",// 二维码链接
 *   }
 * }
 * */
function createPayOrderWeb(req, res, next) {
    var device = checkUtil.stringFromReq(req, 'device');
    if(!device) {
        return payUtil.ret_func_json(0,CODE.DEVICE_EMPTY,{},res);
    }

    var uuid = checkUtil.stringFromReq(req, 'uuid');
    if(!uuid) {
        return payUtil.ret_func_json(0,CODE.UUID_EMPTY,{},res);
    }

    var userId = checkUtil.numberFromReq(req, 'userId');
    if(!userId) {
        return payUtil.ret_func_json(0,CODE.USER_ID_EMPTY,{},res);
    }

    var tradeObjId = checkUtil.numberFromReq(req, 'tradeObjId');
    if(!tradeObjId) {
        return payUtil.ret_func_json(0,'订单ID为空',{},res);
    }

    var type = checkUtil.numberFromReq(req, 'type');
    if(!type) {
        return payUtil.ret_func_json(0,'订单类型为空',{},res);
    }

    payUtil.getUnifiedOrderWeb(device, userId, tradeObjId, type, function(error, ret){
        if(error){
            console.log(error);
            return payUtil.ret_func_json(0, error||CODE.OPERATION_FAILED,{},res);
        }
        return payUtil.ret_func_json(1, CODE.OPERATION_SUCCESS,ret,res);
    });
}
router.get('/createPayOrderWeb', createPayOrderWeb);
router.post('/createPayOrderWeb', createPayOrderWeb);

//------------------------------------------------------------------
/* 创建购买模板支付订单 (APP支付/H5支付)
 * 方式:POST
 * 参数: device: 请求来源
 * 参数: uuid: 设备唯一标识
 * 参数: userId: 用户唯一标识
 * 参数: openId[可选]: (微信H5支付用)
 * 参数: typeL: 模版类型
 * 参数: designId: 模版id
 * 返回:
 * {"success":1,
 *  "msg":"成功",
 *  "data":{
 *      "out_trade_no": "1234567890"
 *      "prepayId": 1234567,
 *      "nonceStr": "qwertyuiopsdfghjkl",
 *      "timeStamp": 999990909090,
 *      "sign": "QWKSJDFHGJHDFHHDHH"
 *   }
 * }
 * */
function createPayOrderForTmpl(req, res, next) {
    var device = checkUtil.stringFromReq(req, 'device');
    if(!device) {
        return payUtil.ret_func_json(0,CODE.DEVICE_EMPTY,{},res);
    }

    var uuid = checkUtil.stringFromReq(req, 'uuid');
    if(!uuid) {
        return payUtil.ret_func_json(0,CODE.UUID_EMPTY,{},res);
    }

    var userId = checkUtil.numberFromReq(req, 'userId');
    if(!userId) {
        return payUtil.ret_func_json(0,CODE.USER_ID_EMPTY,{},res);
    }

    var openId = checkUtil.stringFromReq(req, 'openId') || '';

    var typeL = checkUtil.numberFromReq(req, 'typeL');
    if(!typeL) {
        return payUtil.ret_func_json(0,'模版类型为空',{},res);
    }

    var designId = checkUtil.numberFromReq(req, 'designId');
    if(!designId) {
        return payUtil.ret_func_json(0,'模版ID为空',{},res);
    }

    payUtil.getUnifiedOrderForTmpl(device, userId, openId, typeL, designId, function(error, ret){
        if(error){
            console.log(error);
            return payUtil.ret_func_json(0, error||CODE.OPERATION_FAILED,{},res);
        }
        return payUtil.ret_func_json(1, CODE.OPERATION_SUCCESS,ret,res);
    });
}
router.get('/createPayOrderForTmpl', createPayOrderForTmpl);
router.post('/createPayOrderForTmpl', createPayOrderForTmpl);

//------------------------------------------------------------------
/* 创建购买模板支付订单 (网页支付)
 * 方式:POST
 * 参数: device: 请求来源
 * 参数: uuid: 设备唯一标识
 * 参数: userId: 用户唯一标识
 * 参数: typeL: 模版类型
 * 参数: designId: 模版id
 * 返回:
 * {"success":1,
 *  "msg":"成功",
 *  "data":{
 *      "prepay_id": "wx20170301114917740287da3c0256350262",
 *      "code_url": "weixin://wxpay/bizpayurl?pr=8RODogK",// 二维码链接
 *   }
 * }
 * */
function createPayOrderForTmplWeb(req, res, next) {
    var device = checkUtil.stringFromReq(req, 'device');
    if(!device) {
        return payUtil.ret_func_json(0,CODE.DEVICE_EMPTY,{},res);
    }

    var uuid = checkUtil.stringFromReq(req, 'uuid');
    if(!uuid) {
        return payUtil.ret_func_json(0,CODE.UUID_EMPTY,{},res);
    }

    var userId = checkUtil.numberFromReq(req, 'userId');
    if(!userId) {
        return payUtil.ret_func_json(0,CODE.USER_ID_EMPTY,{},res);
    }

    var typeL = checkUtil.numberFromReq(req, 'typeL');
    if(!typeL) {
        return payUtil.ret_func_json(0,'模版类型为空',{},res);
    }

    var designId = checkUtil.numberFromReq(req, 'designId');
    if(!designId) {
        return payUtil.ret_func_json(0,'模版ID为空',{},res);
    }

    payUtil.getUnifiedOrderForTmplWeb(device, userId, typeL, designId, function(error, ret){
        if(error){
            console.log(error);
            return payUtil.ret_func_json(0, error||CODE.OPERATION_FAILED,{},res);
        }
        return payUtil.ret_func_json(1, CODE.OPERATION_SUCCESS,ret,res);
    });
}
router.get('/createPayOrderForTmplWeb', createPayOrderForTmplWeb);
router.post('/createPayOrderForTmplWeb', createPayOrderForTmplWeb);

//------------------------------------------------------------------
/* 支付完成后，微信会把相关支付结果和用户信息发送给商户(APP用)
 * 方式:POST
 * 参数: xml
 * */
function chkWxPayNotify(req, res, next) {
    // get parameter
    var xmlObj = {};
    if(CONFIG.DEBUG) {
        xmlObj = req.body.sjg_xml.xml|| {};// DEBUG
    } else {
        xmlObj = req.body.xml || {};// 参考: https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_7&index=3
    }

    var retCd = xmlObj.return_code||'UNKNOWN';
    console.log("payment.js [chkPayNotify] RetCd: "+ (xmlObj.return_code||'Unknown'));
    if(retCd == 'SUCCESS') {
        payUtil.chkWxPayNotify(xmlObj, function(err,ret){
            if(err) {
                return retFunc(0);
            }
            return retFunc(1);
        });
    } else {
        return retFunc(0);
    }

    function retFunc(ok){
        var ret2wx = '';
        if(ok==1) {
            ret2wx = '<xml>'+
                '<return_code><![CDATA[SUCCESS]]></return_code>'+
                '<return_msg><![CDATA[OK]]></return_msg>'+
                '</xml>';
        }else{
            ret2wx = '<xml>'+
                '<return_code><![CDATA[FAIL]]></return_code>'+
                '<return_msg><![CDATA[NG]]></return_msg>'+
                '</xml>';
        }
        res.end(ret2wx);
    }
}
router.get('/chkWxPayNotify', chkWxPayNotify);
router.post('/chkWxPayNotify', chkWxPayNotify);

// H5用
function chkWxPayNotify2(req, res, next) {
    // get parameter
    var xmlObj = {};
    if(CONFIG.DEBUG) {
        xmlObj = req.body.sjg_xml.xml|| {};// DEBUG
    } else {
        xmlObj = req.body.xml || {};// 参考: https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_7&index=3
    }

    var retCd = xmlObj.return_code||'UNKNOWN';
    console.log("payment.js [chkPayNotify2] RetCd: "+ (xmlObj.return_code||'Unknown'));
    if(retCd == 'SUCCESS') {
        payUtil.chkWxPayNotify2(xmlObj, function(err,ret){
            if(err) {
                return retFunc(0);
            }
            return retFunc(1);
        });
    } else {
        return retFunc(0);
    }

    function retFunc(ok){
        var ret2wx = '';
        if(ok==1) {
            ret2wx = '<xml>'+
                '<return_code><![CDATA[SUCCESS]]></return_code>'+
                '<return_msg><![CDATA[OK]]></return_msg>'+
                '</xml>';
        }else{
            ret2wx = '<xml>'+
                '<return_code><![CDATA[FAIL]]></return_code>'+
                '<return_msg><![CDATA[NG]]></return_msg>'+
                '</xml>';
        }
        res.end(ret2wx);
    }
}
router.get('/chkWxPayNotify2', chkWxPayNotify2);
router.post('/chkWxPayNotify2', chkWxPayNotify2);

//------------------------------------------------------------------
/* 确认订单支付状态
 * 方式:POST
 * 参数: device: 请求来源
 * 参数: uuid: 设备唯一标识
 * 参数: userId: 用户唯一标识
 * 参数: tradeObjNo: 订单编号: order_no(商品)/inv_no(发票)/buy_no(模版)
 * 参数: type: 商品订单:10, 发票订单:20, 模版订单:30
 * 返回:
 * {"success":1,
 *  "msg":"成功",
 *  "data":{
 *      "trade_state": SUCCESS (参考 https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_2&index=4)
 *   }
 * }
 * */
function checkOrder(req, res, next) {
    var device = checkUtil.stringFromReq(req, 'device');
    if(!device) {
        return payUtil.ret_func_json(0,CODE.DEVICE_EMPTY,{},res);
    }

    var uuid = checkUtil.stringFromReq(req, 'uuid');
    if(!uuid) {
        return payUtil.ret_func_json(0,CODE.UUID_EMPTY,{},res);
    }

    var userId = checkUtil.numberFromReq(req, 'userId');
    if(!userId) {
        return payUtil.ret_func_json(0,CODE.USER_ID_EMPTY,{},res);
    }

    var tradeObjNo = checkUtil.stringFromReq(req, 'tradeObjNo');
    if(!tradeObjNo) {
        return payUtil.ret_func_json(0,'订单号为空',{},res);
    }

    var type = checkUtil.numberFromReq(req, 'type');
    if(!type) {
        return payUtil.ret_func_json(0,'订单类型为空',{},res);
    }

    payUtil.checkOrder(device, userId, tradeObjNo, type, function(error, ret){
        if(error){
            console.log(error);
            return payUtil.ret_func_json(0, CODE.OPERATION_FAILED,{},res);
        }

        return payUtil.ret_func_json(1, CODE.OPERATION_SUCCESS,ret,res);
    });
}
router.get('/checkOrder', checkOrder);
router.post('/checkOrder', checkOrder);

//------------------------------------------------------------------
function test(req, res, next) {
    var tradeId = checkUtil.numberFromReq(req, 'tradeId');
    if(!tradeId) {
        return payUtil.ret_func_json(0,'tradeId为空',{},res);
    }

    var tradeType = checkUtil.stringFromReq(req, 'tradeType');
    if(!tradeType) {
        return payUtil.ret_func_json(0,'tradeType为空',{},res);
    }

    payUtil.tryCopyOrderAddressToUser(tradeId, tradeType, function(error, ret){
        if(error){
            console.log(error);
            return payUtil.ret_func_json(0, CODE.OPERATION_FAILED,{},res);
        }

        return payUtil.ret_func_json(1, CODE.OPERATION_SUCCESS,ret,res);
    });
}
router.get('/test', test);
router.post('/test', test);

//-----------------------------确认网页订单支付结果------------------------------------
/**
 * 参数: device	"0表示从pc来的请求
 1表示ios
 2表示android
 101表示pc美化大师/102表示pc wps/103表示wps android/104表示wps ios
 3 标示app 嵌入网页"
 4 标识 网页版

 参数: userId	用户唯一标识
 参数: orderId	订单 id

 * */
// todo 新增接口, 待审核 begin
function chkTradeOrderState_v5_2(req, res, next){
    var device = checkUtil.numberFromReq(req, 'device');
    var userId = checkUtil.numberFromReq(req, 'userId');
    if(!userId){
        return payUtil.ret_func_json(0,'userId 为空',{},res);
    }

    var orderId = checkUtil.numberFromReq(req, 'orderId');
    if(!orderId) {
        return payUtil.ret_func_json(0,'orderId为空',{},res);
    }

    res.setTimeout(5*60*1000 + 5); // 设置请求5分钟超时
    var count = 0;  // 查询次数
    var timer = setInterval(function(){
        count ++;
        // 最多查询 5 * 30 次, 共 5 * 30 * 2 = 5分钟
        if(count >= 5* 30) {
            clearInterval(timer);
            return payUtil.ret_func_json(0, '支付超时', {}, res);
        }
        payUtil.getTradeOrderState_v5_2(orderId, userId, function(error, state){
            // '订单状态:10待支付、11已支付、12支付失败、20制作中、30配送中、40完成、50取消'

            if(error) {
                console.log('payment.js [chkTradeOrderState_v5_2] err: ' + error);
                clearInterval(timer);
                return payUtil.ret_func_json(0, CODE.OPERATION_FAILED, {}, res);;
            }

            // 订单状态为 待支付, 或支付失败的时候, 等待, 继续轮询
            if(state == 10 || state == 12) {
                // console.log('payment.js [chkTradeOrderState_v5_2] orderId: ' + orderId + ' state: ' + state + ' count: ' + count);
                return;
            }
            clearInterval(timer);
            return payUtil.ret_func_json(1, CODE.OPERATION_SUCCESS, {orderId : orderId, state : state}, res);
        });

    }, 2000); // 每 2 秒查询一次
}
router.get('/chkTradeOrderState_v5_2', chkTradeOrderState_v5_2);
router.post('/chkTradeOrderState_v5_2', chkTradeOrderState_v5_2);

// todo 新增接口, 待审核 end
//------------------------------------------------------------------
module.exports = router;
